/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.engine.cmd.list;

import cn.easyplatform.EntityNotFoundException;
import cn.easyplatform.contexts.ListContext;
import cn.easyplatform.contexts.RecordContext;
import cn.easyplatform.contexts.WorkflowContext;
import cn.easyplatform.dos.Record;
import cn.easyplatform.engine.runtime.PageTaskSupport;
import cn.easyplatform.engine.runtime.RuntimeTask;
import cn.easyplatform.engine.runtime.datalist.DataListUtils;
import cn.easyplatform.engine.runtime.page.PageTask;
import cn.easyplatform.entities.beans.page.PageBean;
import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.interceptor.AbstractCommand;
import cn.easyplatform.interceptor.CommandContext;
import cn.easyplatform.lang.Lang;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.messages.request.ListOpenRequestMessage;
import cn.easyplatform.messages.response.SimpleResponseMessage;
import cn.easyplatform.messages.vos.datalist.ListOpenVo;
import cn.easyplatform.support.scripting.BreakPoint;
import cn.easyplatform.type.Constants;
import cn.easyplatform.type.EntityType;
import cn.easyplatform.type.IResponseMessage;
import cn.easyplatform.util.MessageUtils;
import cn.easyplatform.util.RuntimeUtils;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class OpenCmd extends AbstractCommand<ListOpenRequestMessage> {

	public OpenCmd(ListOpenRequestMessage req) {
		super(req);
	}

	@Override
	public IResponseMessage<?> execute(CommandContext cc) {
		if (req.getActionFlag() < 0) {
			cc.setBreakPoint(null);
			cc.removeWorkflowContext();
			return new SimpleResponseMessage();
		}
		BreakPoint bp = cc.getBreakPoint();
		if (bp == null) {
			ListOpenVo lov = req.getBody();
			WorkflowContext ctx = cc.getWorkflowContext();
			ListContext lc = ctx.getList(lov.getId());
			if (lc == null)
				return MessageUtils.dataListNotFound(lov.getId());
			PageBean pb = cc.getEntity(lov.getPageId());
			if (pb == null)
				return MessageUtils.entityNotFound(EntityType.PAGE.getName(),
						lov.getPageId());
			if (!lc.getBean().getTable().equals(pb.getTable()))
				return MessageUtils.entityNotFound(EntityType.PAGE.getName(),
						lov.getPageId());
			// 新建
			if (lov.getProcessCode().equals("C"))
				return doCreate(cc, ctx, lov, lc, pb);
			else
				return doTask(cc, ctx, lov, lc, pb);
		} else {
			PageTaskSupport ps = new PageTask();
			IResponseMessage<?> resp = ps.doPageBreakPoint(cc, bp);
			if (!resp.isSuccess()) {
				char c = resp.getCode().toLowerCase().charAt(0);
				if (c != 'c' && c != 'w')
					cc.removeWorkflowContext();
			}
			return resp;
		}
	}

	private IResponseMessage<?> doTask(CommandContext cc, WorkflowContext host,
			ListOpenVo lov, ListContext lc, PageBean pb) {
		RecordContext rc = lc.getRecord(lov.getKeys());
		if (rc == null && lc.getType().equals(Constants.CATALOG)) {
			Record record = DataListUtils.getRecord(cc, lc, lov.getKeys());
			rc = lc.createRecord(lov.getKeys(), record);
			rc.setParameter("814", 'R');
			rc.setParameter("815", Boolean.FALSE);
		}
		if (rc == null)
			return MessageUtils.recordNotFound(pb.getTable(),
					Lang.concat(lov.getKeys()).toString());
		WorkflowContext ctx = new WorkflowContext(lc, lov.getOpenModel(), rc);
		if (ctx.getParameterAsChar("814") != 'C') {
			lc.lock(cc, lov.getKeys());
			ctx.setParameter("814", lov.getProcessCode());
		}
		if (lov.getOpenModel() == Constants.OPEN_EMBBED)
			cc.remove(host.getParameterAsString("800") + lc.getId());
		cc.setWorkflowContext(ctx);
		RuntimeTask rt = new PageTask();
		IResponseMessage<?> resp = rt.doTask(cc, pb);
		if (!resp.isSuccess()) {
			char c = resp.getCode().toLowerCase().charAt(0);
			if (c != 'c' && c != 'w')
				cc.removeWorkflowContext();
		}
		return resp;
	}

	private IResponseMessage<?> doCreate(CommandContext cc,
			WorkflowContext host, ListOpenVo lov, ListContext lc, PageBean pb) {
		TableBean table = cc.getEntity(pb.getTable());
		if (table == null)
			throw new EntityNotFoundException(EntityType.TABLE.getName(),
					pb.getTable());
		RecordContext rc = null;
		if (lov.getCopyKeys() != null) {
			RecordContext from = lc.getRecord(lov.getCopyKeys());
			rc = from.create();
			rc.setData(from.getData().clone());
			if (table.isAutoKey())
				rc.setValue(table.getKey().get(0), cc.getIdGenerator()
						.getNextId(table.getId()));
		} else
			rc = lc.createRecord(RuntimeUtils.createRecord(cc, table,
					table.isAutoKey()));
		if (!Strings.isBlank(lc.getBeforeLogic())) {
			RecordContext[] rcs = new RecordContext[2];
			if (!Strings.isBlank(lc.getHost())) {
				ListContext fc = host.getList(lc.getHost());
				if (fc == null)
					return MessageUtils.dataListNotFound(lc.getHost());
				RecordContext r = fc.getRecord(lov.getKeys());
				if (r == null && fc.getType().equals(Constants.CATALOG)) {
					Record record = DataListUtils.getRecord(cc, fc,
							lov.getKeys());
					r = lc.createRecord(lov.getKeys(), record);
					r.setParameter("815", false);
					r.setParameter("814", "R");
					fc.appendRecord(r);
				}
				if (r == null)
					return MessageUtils.recordNotFound(fc.getBean().getTable(),
							Lang.concat(lov.getKeys()).toString());
				rcs[0] = r;
			} else
				rcs[0] = host.getRecord();
			rcs[1] = rc;
			String result = RuntimeUtils.eval(cc, lc.getBeforeLogic(), rcs);
			if (!result.equals("0000"))
				return MessageUtils.byErrorCode(cc, host.getRecord(),
						host.getId(), result);
		}
		WorkflowContext ctx = new WorkflowContext(lc, lov.getOpenModel(), rc);
		ctx.setParameter("814", "C");
		ctx.setParameter("815", true);
		if (lov.getOpenModel() == Constants.OPEN_EMBBED)
			cc.remove(host.getParameterAsString("800") + lc.getId());
		cc.setWorkflowContext(ctx);
		RuntimeTask rt = new PageTask();
		IResponseMessage<?> resp = rt.doTask(cc, pb);
		if (!resp.isSuccess()) {
			char c = resp.getCode().toLowerCase().charAt(0);
			if (c != 'c' && c != 'w')
				cc.removeWorkflowContext();
		}
		return resp;

	}

	@Override
	public String getName() {
		return "list.Open";
	}
}
